package com.hrc.springbootdemo.ws.service.impl;


import com.hrc.springbootdemo.ws.entity.ClientUserInfo;
import com.hrc.springbootdemo.ws.service.WebSocketService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;


@Slf4j
@Service
public class WebSocketServiceImpl implements WebSocketService {

    private final Map<Integer, WebSocketSession> clients = new ConcurrentHashMap<>();

    @Override
    public void handleOpen(WebSocketSession session) {
        // 这个时候就需要在建立 webSocket 时存储的 用户信息了
        Map<String, Object> attributes = session.getAttributes();
        ClientUserInfo clientUserInfo = (ClientUserInfo) attributes.get("clientUserInfo");
        if (clientUserInfo == null) {
            clientUserInfo = new ClientUserInfo();
            clientUserInfo.setId(new Random().nextInt(1000000000));
            attributes.put("clientUserInfo", clientUserInfo);
        }
        clients.put(clientUserInfo.getId(), session);

        log.info("a new connection opened，current online count：{}", clients.size());
    }

    @Override
    public void handleClose(WebSocketSession session) {
        // 这个时候就需要在建立 webSocket 时存储的 用户信息了
        Map<String, Object> attributes = session.getAttributes();
        ClientUserInfo clientUserInfo = (ClientUserInfo) attributes.get("clientUserInfo");
        clients.remove(clientUserInfo.getId());
        log.info("a new connection closed，current online count：{}", clients.size());
    }

    @Override
    public void handleMessage(WebSocketSession session, String message) {
        // 只处理前端传来的文本消息，并且直接丢弃了客户端传来的消息
        log.info("received a message：{}", message);
        try {
            session.sendMessage(new TextMessage(message));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void sendMessage(WebSocketSession session, String message) throws IOException {
        this.sendMessage(session, new TextMessage(message));
    }

    @Override
    public void sendMessage(Integer userId, TextMessage message) throws IOException {
        WebSocketSession webSocketSession = clients.get(userId);

        if (webSocketSession.isOpen()) {
            webSocketSession.sendMessage(message);
        }
    }

    @Override
    public void sendMessage(Integer userId, String message) throws IOException {
        this.sendMessage(userId, new TextMessage(message));
    }

    @Override
    public void sendMessage(WebSocketSession session, TextMessage message) throws IOException {
        session.sendMessage(message);
    }

    @Override
    public void broadCast(String message) throws IOException {
        clients.values().forEach(session -> {
            if (session.isOpen()) {
                try {
                    session.sendMessage(new TextMessage(message));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    @Override
    public void broadCast(TextMessage message) throws IOException {
        clients.values().forEach(session -> {
            if (session.isOpen()) {
                try {
                    session.sendMessage(message);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    @Override
    public void handleError(WebSocketSession session, Throwable error) {
        log.error("websocket error：{}，session id：{}", error.getMessage(), session.getId());
        log.error("", error);
    }

}

